#pragma once
#include <QObject>
#include "../../Config.h"
#include "../../Global.h"

static const bool ShowFPS = false;
static const int FPSAverageFrames = 3;
static const bool DisplayAllFeaturesOneByOne = false;
static const bool ShowZhichePng = true;

/**
 * @brief communication: C++ <==> QML
 */
class QDynQml : public QObject {
	Q_OBJECT
	Q_PROPERTY(QString bgPath READ bgPath WRITE setBgPath NOTIFY bgPathChange)
	Q_PROPERTY(bool zhichePngVisible READ zhichePngVisible WRITE setZhichePngVisible NOTIFY zhichePngVisibleChange)
	Q_PROPERTY(QString zhichePngPath READ zhichePngPath WRITE setZhichePngPath NOTIFY zhichePngPathChange)

	Q_PROPERTY(bool debugMsgVisible READ debugMsgVisible WRITE setDebugMsgVisible NOTIFY debugMsgVisibleChange)
	Q_PROPERTY(QString debugMsg READ debugMsg WRITE setDebugMsg NOTIFY debugMsgChange)

	Q_PROPERTY(bool fpsEnabled READ fpsEnabled WRITE setFPSEnabled NOTIFY fpsEnableChanged)
	Q_PROPERTY(int fps READ fps WRITE setFPS NOTIFY fpsValueChanged)
	Q_PROPERTY(bool displayAllFeatures READ displayAllFeatures WRITE setDisplayAllFeatures NOTIFY displayAllFeaturesChange)
	Q_PROPERTY(Feature feature READ feature WRITE setFeature NOTIFY featureChanged)
public:
	enum Feature { ALC = 1, DCLC = 2, ACC_FD = 3, LDW = 4, ACC_TG = 5, LampBrake = 6, LampTurn = 7, ZhicheDoor = 8 };
	Q_ENUM(Feature)

	static QDynQml* get() {
		static auto* instance = new QDynQml;
		return instance;
	}

	// qml getters
	QString bgPath() { return m_bgPath; }
	bool zhichePngVisible() { return m_zhichePngVisible; }
	QString zhichePngPath() { return m_zhichePngPath; }

	bool fpsEnabled() const { return ShowFPS; }
	int fps() const { return m_fps; }
	bool displayAllFeatures() const { return DisplayAllFeaturesOneByOne; }
	Feature feature() const { return m_feature; }

	bool debugMsgVisible() { return m_isDebugMsgVisible; }
	QString debugMsg() { return m_debugMsg; }

	// c++ setters
	void setZhichePngVisible(bool visible) {
		if (m_zhichePngVisible == visible) return;
		m_zhichePngVisible = visible;
		emit zhichePngVisibleChange(visible);
	}

	void setZhichePngPath(const QString& path) {}

	void setBgPath(const QString& path) {}

	void setFPSEnabled(bool isEnabled) {}
	void setFPS(int fps) {
		m_fps = fps;
		emit fpsValueChanged(fps);
	}
	void setDisplayAllFeatures(bool isEnabled) {}
	void setFeature(Feature feature) {
		m_feature = feature;
		emit featureChanged(feature);
	}

	void setDebugMsgVisible(bool visible) { m_isDebugMsgVisible = visible; }
	void setDebugMsg(const QString& msg) {
		if (!m_isDebugMsgVisible) {
			setDebugMsgVisible(true);
			emit debugMsgVisibleChange(true);
		}
		m_debugMsg = msg;
		emit debugMsgChange(msg);
	}

signals:// c++ -> qml
	void zhichePngVisibleChange(bool);
	void zhichePngPathChange(const QString&);
	void bgPathChange(const QString&);

	void fpsEnableChanged(bool isEnabled);
	void fpsValueChanged(int fps);
	void displayAllFeaturesChange(bool isEnabled);
	void featureChanged(int feature);

	void debugMsgVisibleChange(bool);
	void debugMsgChange(const QString&);

public slots:// qml -> c++
	void zhichePngVisibleChanged(bool) {}
	void zhichePngPathChanged(const QString&) {}
	void bgPathChanged(const QString&) {}

	void debugMsgVisibleChanged(bool) {}
	void debugMsgChanged(const QString& msg) {}
private:
	QDynQml() = default;

	bool m_zhichePngVisible = ShowZhichePng;// def:true
	QString m_zhichePngPath = QString::fromStdString(Config::getQmlRelativeLocalEnvPath(Config::View3D_ZhichePngPath));
	QString m_bgPath = QString::fromStdString(Config::getQmlRelativeLocalEnvPath(Global::isDarkMode() ? Config::View3D_BgDarkImgPath : Config::View3D_BgLightImgPath));

	int m_fps = 0;
	Feature m_feature;

	bool m_isDebugMsgVisible = false;
	QString m_debugMsg;
};